package dq.study.concurrent.monitor;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition将监视器方法分解成不同的对象，以便将这些对象结合不同的lock使用
 *
 * @author dongqun
 * @date 2020/1/21 18:19
 */
public class CondtionTest {
    public static ReentrantLock lock = new ReentrantLock();
    public static Condition conditionA = lock.newCondition();
    public static Condition conditionB = lock.newCondition();
    public static Condition conditionC = lock.newCondition();
    public static int index = 0;

    public static void main(String[] args) throws InterruptedException {
        ThreadA threadA = new ThreadA();
        ThreadB threadB = new ThreadB();
        ThreadC threadC = new ThreadC();
        // A--B--C 顺序执行时可以正常停止
        threadA.start();//（1）
        Thread.sleep(1000);
        threadB.start();//（2）
        Thread.sleep(1000);
        threadC.start();//（3）
    }


    public static class ThreadA extends Thread{
        @Override
        public void run(){
            try{
                lock.lock();
                System.out.println("A进程输出" + " : " + ++index);
                conditionB.signal();
                conditionC.await();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
                System.out.println("A进程结束");
            }
        }
    }



    public static class ThreadB extends Thread{
        @Override
        public void run(){
            try{
                lock.lock();
                System.out.println("B进程输出" + " : " + ++index);
                conditionC.signal();
                conditionA.await();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
                System.out.println("B进程结束");
            }
        }
    }


    public static class ThreadC extends Thread{
        @Override
        public void run(){
            try{
                lock.lock();
                System.out.println("C进程输出" + " : " + ++index);
                conditionA.signal();
//                conditionB.signal();
//                conditionC.signal();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
                System.out.println("C进程结束");
            }
        }
    }

}
